﻿using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using System.Threading;

namespace 非对称加密
{
    /// <summary> 
    /// Form1 的摘要说明。 
    /// </summary> 
    public partial class  Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.TabControl tabControl1;
        private System.Windows.Forms.TabPage tabPage1;
        private System.Windows.Forms.TabPage tabPage2;
        private System.Windows.Forms.TabPage tabPage3;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
        private System.Windows.Forms.Button button3;
        private System.Windows.Forms.SaveFileDialog save;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.Button button4;
        private System.Windows.Forms.Button button5;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.RichTextBox richtext2;
        private System.Windows.Forms.OpenFileDialog open;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.RichTextBox richtext3;
        private System.Windows.Forms.RichTextBox richtext;
        private System.Windows.Forms.Button button6;
        private System.Windows.Forms.Button button7;
        private System.Windows.Forms.Button button8;
        private System.Windows.Forms.TextBox textBox2;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.Button button9;
        private System.Windows.Forms.TextBox textBox3;
        private System.Windows.Forms.Label label5;
        private System.Windows.Forms.Button button10;
        private System.Windows.Forms.Label label6;
        private System.Windows.Forms.Button button11;
        private System.Windows.Forms.Button button12;
        private System.Windows.Forms.RichTextBox richtext4;
        private System.Windows.Forms.Button button13;
        private System.Windows.Forms.Button button14;
        private System.Windows.Forms.Button button15;
        private System.Windows.Forms.TabPage tabPage4;
        private System.Windows.Forms.TextBox textBox4;
        private System.Windows.Forms.Button button16;
        private System.Windows.Forms.TextBox textBox5;
        private System.Windows.Forms.Button button17;
        private System.Windows.Forms.Button button18;
        private System.Windows.Forms.Button button19;
        private System.Windows.Forms.Button button20;
        private System.Windows.Forms.Button button21;
        private System.Windows.Forms.RichTextBox richtext5;
        /// <summary> 
        /// 必需的设计器变量。 
        private static RSACryptoServiceProvider crypt;
        private static string privatekey;
        private static string publickey;
        private static byte[] bytes;
        private static string publicinfo="tmp.txt";
        private static string privateinfo;
        private static string readpublickey;
        private static string readprivatekey;
        //文件打开和是否读取钥匙的标记 
        private bool openla = false;
        private bool savela = false;
        private bool readpubkey = false;
        private bool readprikey = false;
        private Thread th;
        /// </summary> 
      

        public Form1()
        {
            // 
            // Windows 窗体设计器支持所必需的 
            // 
      InitializeComponent();

            // 
            // TODO: 在 InitializeComponent 调用后添加任何构造函数代码 
            // 
        }
        /// <summary> 
        /// 清理所有正在使用的资源。 
        /// </summary> 
       
        #region Windows 窗体设计器生成的代码
        /// <summary> 
        /// 设计器支持所需的方法 - 不要使用代码编辑器修改 
        /// 此方法的内容。 
        /// </summary> 
      
        #endregion

        //得到钥匙信息 
        private void button1_Click(object sender, System.EventArgs e)
        {
            crypt = new RSACryptoServiceProvider();
            publickey = crypt.ToXmlString(false);
            richtext.Text = "导出秘匙的情况下：\n" + publickey + "\n";
            privatekey = crypt.ToXmlString(true);
            string info = "仅仅导出公匙的情况下：\n" + privatekey + "\n";
            richtext.AppendText(info);
            crypt.Clear();
        }
        //保存公匙信息 
        private void button2_Click(object sender, System.EventArgs e)
        {

            save = new SaveFileDialog();
            save.Filter = "File Text (*.txt)|*.txt|All File (*.*)|*.*";
            save.ShowDialog();
            publicinfo = save.FileName;
        }
        //保存密匙信息 
        private void button3_Click(object sender, System.EventArgs e)
        {
            save = new SaveFileDialog();
            save.Filter = "File Text (*.txt)|*.txt|All File (*.*)|*.*";
            save.ShowDialog();
            privateinfo = save.FileName;
        }
        //用公匙加密 
        private void button4_Click(object sender, System.EventArgs e)
        {
            if (textBox1.Text == "")
            {
                MessageBox.Show("加密文字信息不能为空！");
                return;
            }
            if (readpubkey == false)
            {
                MessageBox.Show("请打开公钥所在的文件！");
                return;
            }
            try
            {
                crypt = new RSACryptoServiceProvider();
                UTF8Encoding enc = new UTF8Encoding();
                bytes = enc.GetBytes(textBox1.Text);
                crypt.FromXmlString(readpublickey);
                bytes = crypt.Encrypt(bytes, false);
                string encryttext = enc.GetString(bytes);
                richtext2.Text = "加密结果：\n" + encryttext + "\n" + "加密结束！";
            }
            catch
            {
                MessageBox.Show("请检查是否打开公匙或者公匙是否损坏！");

            }
        }
        //使用私匙解密 
        private void button5_Click(object sender, System.EventArgs e)
        {
            if (readprikey == false)
            {
                MessageBox.Show("请打开密匙所在的文件！");
                return;
            }
            try
            {
                UTF8Encoding enc = new UTF8Encoding();
                byte[] decryptbyte;
                crypt.FromXmlString(readprivatekey);
                decryptbyte = crypt.Decrypt(bytes, false);
                string decrypttext = enc.GetString(decryptbyte);
                richtext3.Text = "解密结果：\n" + decrypttext + "\n" + "解密结束！";
            }
            catch
            {
                MessageBox.Show("请检查是否打开私匙或者私匙是否损坏！");

            }
        }
        //把钥匙信息写入文件 
        private void button6_Click(object sender, System.EventArgs e)
        {
            StreamWriter one = new StreamWriter(publicinfo, true, UTF8Encoding.UTF8);
            one.Write(publickey);
            StreamWriter two = new StreamWriter(privateinfo, true, UTF8Encoding.UTF8);
            two.Write(privatekey);
            one.Flush();
            two.Flush();
            one.Close();
            two.Close();
            MessageBox.Show("成功保存公匙和密匙！");
        }
        //从文件中读取公匙信息 
        private void button7_Click(object sender, System.EventArgs e)
        {
            readpublickey = ReadPublicKey();
            readpubkey = true;
        }

        //从文件中读取私匙信息 
        private void button8_Click(object sender, System.EventArgs e)
        {

            readprivatekey = ReadPrivateKey();
            readprikey = true;
        }

        //打开加密或者解密的文件 
        private void button9_Click(object sender, System.EventArgs e)
        {
            open = new OpenFileDialog();
            open.Filter = "Text File (*.txt)|*.txt|All Files (*.*)|*.*";
            open.ShowDialog();
            textBox2.Text = open.FileName;
            openla = true;
        }
        //保存加密或者解密的文件 
        private void button10_Click(object sender, System.EventArgs e)
        {
            try
            {
                save = new SaveFileDialog();
                save.Filter = "File Text (*.txt)|*.txt|All File (*.*)|*.*";
                save.ShowDialog();
                textBox3.Text = save.FileName;
                savela = true;
            }
            catch
            {
                MessageBox.Show("请输入文件名字！");
                return;
            }

        }

        //加密文本文件 
        private void button11_Click(object sender, System.EventArgs e)
        {
            if (readpubkey != true)
            {
                MessageBox.Show("请打开公钥所在的文件！");
                return;
            }
            if (openla == true && savela == true)
            {
                crypt = new RSACryptoServiceProvider();
                crypt.FromXmlString(readpublickey);
                UTF8Encoding enc = new UTF8Encoding();
                //读取原文件到一个string 去啊 
                StreamReader sr = new StreamReader(textBox2.Text, Encoding.Default);
                string textinfo = sr.ReadToEnd();
                sr.Close();
                // richtext4.AppendText( "\n原文件内容：\n" + textinfo + "\n" ); 
                //开始加密 
                string readinfo = EncryptFile(textinfo, textBox3.Text);
                richtext4.AppendText("加密文件已经保存到：" + textBox3.Text + "\n");
                richtext4.AppendText("加密结果：\n" + readinfo + "\n加密结束！");
            }
            else
                MessageBox.Show("请选择你要加密的文件或者要保存的文件！");
        }
        //解密文件 
        private void button12_Click(object sender, System.EventArgs e)
        {
            if (readprikey == false)
            {
                MessageBox.Show("请打开密匙所在的文件！");
                return;
            }
            if (openla == true && savela == true)
            {
                try
                {
                    crypt = new RSACryptoServiceProvider();
                    crypt.FromXmlString(readprivatekey);
                    string decryptinfo = DecryptFile(textBox2.Text, textBox3.Text);
                    richtext4.AppendText("解密文件已经保存到：" + textBox3.Text + "\n");
                    richtext4.AppendText("解密结果：\n" + decryptinfo + "\n" + "解密结束！\n");
                }
                catch
                {
                    MessageBox.Show("请检查密匙文件是否和公匙相对应或者密匙文件损坏！");
                    return;
                }
            }
            else
                MessageBox.Show("请选择你要解密的文件或者要保存的文件！");
        }

        //加密文件时候，同样要打开公钥匙 
        private void button13_Click(object sender, System.EventArgs e)
        {
            readpublickey = ReadPublicKey();
            readpubkey = true;

        }
        //解密文件时候，同样要打开私钥匙 
        private void button14_Click(object sender, System.EventArgs e)
        {
            readprivatekey = ReadPrivateKey();
            readprikey = true;
        }
        private void button15_Click(object sender, System.EventArgs e)
        {
            richtext4.Clear();
        }

        //打开文件 
        private void button16_Click(object sender, System.EventArgs e)
        {
            open = new OpenFileDialog();
            open.Filter = "All Files (*.*)|*.*";
            open.ShowDialog();
            textBox4.Text = open.FileName;
            openla = true;
        }
        //保存文件 
        private void button17_Click(object sender, System.EventArgs e)
        {
            save = new SaveFileDialog();
            save.Filter = "All File (*.*)|*.*";
            save.ShowDialog();
            textBox5.Text = save.FileName;
            savela = true;
        }
        //加密其它非文本文件 
        private void EncryptOther(string file1, string file2)
        {
            FileStream picfs = new FileStream(@file1, FileMode.Open);
            FileStream fs = new FileStream(@file2, FileMode.OpenOrCreate);
            byte[] bytes = new byte[picfs.Length];
            picfs.Read(bytes, 0, (int)picfs.Length);
            picfs.Close();
            int blockSize = 0;
            if (crypt.KeySize == 1024)
                blockSize = 16;
            else blockSize = 8;
            byte[] rawblock, encryblock;
            for (int i = 0; i < bytes.Length; i += blockSize)
            {
                if ((bytes.Length - i) > blockSize)
                    rawblock = new byte[blockSize];
                else rawblock = new byte[bytes.Length - i];
                Buffer.BlockCopy(bytes, i, rawblock, 0, rawblock.Length);
                encryblock = crypt.Encrypt(rawblock, false);
                fs.Write(encryblock, 0, encryblock.Length);
            }
            fs.Flush();
            fs.Close();
        }
        //解密其它非文本文件 
        private void DecryptOther(string fileone, string filetwo)
        {
            FileStream fs = new FileStream(@fileone, FileMode.Open);
            FileStream writopic = new FileStream(@filetwo, FileMode.Create);
            byte[] bytes = new byte[fs.Length];
            fs.Read(bytes, 0, (int)fs.Length);
            fs.Close();
            MemoryStream ms = new MemoryStream();
            int keySize = crypt.KeySize / 8;
            byte[] rawblock, decryptblock;
            for (int i = 0; i < bytes.Length; i += keySize)
            {
                if ((bytes.Length - i) > keySize)
                {
                    rawblock = new byte[keySize];
                }
                else
                { rawblock = new byte[bytes.Length - i]; }

                Buffer.BlockCopy(bytes, i, rawblock, 0, rawblock.Length);
                decryptblock = crypt.Decrypt(rawblock, false);
                ms.Write(decryptblock, 0, decryptblock.Length);
            }
            ms.Position = 0;
            byte[] decode = new byte[ms.Length];
            ms.Read(decode, 0, (int)ms.Length);
            ms.Close();
            writopic.Write(decode, 0, decode.Length);
            writopic.Close();

        }
        //创建一个函数，可以在线程中使用 
        private void DecryptUsingThread()
        {
            DecryptOther(textBox4.Text, textBox5.Text);
        }
        //读取公钥匙 
        private void button18_Click(object sender, System.EventArgs e)
        {
            readpublickey = ReadPublicKey();
            readpubkey = true;
        }
        //读取私钥匙 
        private void button19_Click(object sender, System.EventArgs e)
        {
            readprivatekey = ReadPrivateKey();
            readprikey = true;
        }
        // 加密其它非文本文件啦 
        private void button20_Click(object sender, System.EventArgs e)
        {
            if (readpubkey == false)
            {
                MessageBox.Show("请打开公匙所在的文件！");
                return;
            }
            if (openla == true && savela == true)
            {
                try
                {
                    crypt = new RSACryptoServiceProvider();
                    crypt.FromXmlString(readpublickey);
                    EncryptOther(textBox4.Text, textBox5.Text);
                    richtext5.AppendText("加密过程结束！：\n" + "加密文件已经保存到：\n" + textBox5.Text + "\n");
                }
                catch
                {
                    MessageBox.Show("请检查密匙文件是否和公匙相对应或者密匙文件损坏！");
                    return;
                }
            }
            else
                MessageBox.Show("请选择你要解密的文件或者要保存的文件！");

        }
        //解密其它文件啦 
        private void button21_Click(object sender, System.EventArgs e)
        {
            if (readprikey == false)
            {
                MessageBox.Show("请打开密匙所在的文件！");
                return;
            }
            if (openla == true && savela == true)
            {
                try
                {
                    crypt = new RSACryptoServiceProvider();
                    crypt.FromXmlString(readprivatekey);
                    //使用线程后，反而达不到效果 //原因？暂时不清晰 
                    //可以转换，但是转换要经过几分钟，才可以真正得到想要的转换的东西。 
                    th = new Thread(new ThreadStart(DecryptUsingThread));
                    th.Start();
                    // DecryptOther(textBox4.Text,textBox5.Text); 
                    richtext5.AppendText("解密结束！\n" + "解密文件已经保存到：" + textBox5.Text + "\n");
                }
                catch
                {
                    MessageBox.Show("请检查密匙文件是否和公匙相对应或者密匙文件损坏！");
                    return;
                }
            }
            else
                MessageBox.Show("请选择你要解密的文件或者要保存的文件！");
        }

        //下面为自己定义的函数啦 
        //单独一个读取公匙的函数 
        private string ReadPublicKey()
        {

            string publickey;
            open = new OpenFileDialog();
            open.Filter = "Text File (*.txt)|*.txt|All File (*.*)|*.* ";
            open.ShowDialog();
            StreamReader sr = new StreamReader(open.FileName, UTF8Encoding.UTF8);
            publickey = sr.ReadToEnd();
            sr.Close();
            return publickey;
        }
        //单独一个读取私匙的函数 
        private string ReadPrivateKey()
        {
            string privatekey;
            open = new OpenFileDialog();
            open.Filter = "Text File (*.txt)|*.txt|All File (*.*)|*.* ";
            open.ShowDialog();
            StreamReader sr = new StreamReader(open.FileName, UTF8Encoding.UTF8);
            privatekey = sr.ReadToEnd();
            sr.Close();
            return privatekey;
        }
        //加密文本文件 
        private string EncryptFile(string textinfo, string filename)
        {
            UTF8Encoding enc = new UTF8Encoding();
            byte[] bytes = enc.GetBytes(textinfo);
            int blockSize = 0;
            if (crypt.KeySize == 1024)
                blockSize = 16;
            else
                blockSize = 8;
            //同时写入到内存中去 
            MemoryStream ms = new MemoryStream();
            //写入文件中去啊。 
            FileStream fs = new FileStream(@filename, FileMode.OpenOrCreate);
            byte[] rawblock, encryblock;
            for (int i = 0; i < bytes.Length; i += blockSize)
            {
                if ((bytes.Length - i) > blockSize)
                    rawblock = new byte[blockSize];
                else
                    rawblock = new byte[bytes.Length - i];
                Buffer.BlockCopy(bytes, i, rawblock, 0, rawblock.Length);
                encryblock = crypt.Encrypt(rawblock, false);
                fs.Write(encryblock, 0, encryblock.Length);
                //写入到内存中去啊。 
                ms.Write(encryblock, 0, encryblock.Length);
            }
            //写入到内存中 
            ms.Position = 0;
            byte[] decode = new byte[ms.Length];
            ms.Read(decode, 0, (int)ms.Length);
            string decodeinfo = enc.GetString(decode, 0, decode.Length);
            fs.Flush();
            fs.Close();
            ms.Close();
            return decodeinfo;
        }

        //解密文本文件 
        private string DecryptFile(string encryptfile, string decryptfile)
        {
            //打开加密后的文件，读取文件内容 
            FileStream fs = new FileStream(@encryptfile, FileMode.Open);
            byte[] bytes = new byte[fs.Length];
            fs.Read(bytes, 0, (int)fs.Length);
            fs.Close();
            //先写入到内存 
            MemoryStream ms = new MemoryStream();
            //最好写入到解密后的一个文件 
            StreamWriter sw = new StreamWriter(decryptfile);
            int keySize = crypt.KeySize / 8;
            byte[] rawblock, decryptblock;
            for (int i = 0; i < bytes.Length; i += keySize)
            {
                if ((bytes.Length - i) > keySize)
                {
                    rawblock = new byte[keySize];
                }
                else
                { rawblock = new byte[bytes.Length - i]; }

                Buffer.BlockCopy(bytes, i, rawblock, 0, rawblock.Length);
                decryptblock = crypt.Decrypt(rawblock, false);
                ms.Write(decryptblock, 0, decryptblock.Length);
            }
            ms.Position = 0;
            byte[] decode = new byte[ms.Length];
            ms.Read(decode, 0, (int)ms.Length);
            UTF8Encoding enc = new UTF8Encoding();
            string text = enc.GetString(decode);
            //写入到内存中去啊 
            sw.Write(text);
            sw.Flush();
            ms.Close();
            sw.Close();
            return text;
        }


        //加密其它非文本文件，当然可以包括文本文件 
        //private void EncryptOther(string file1, string file2)
        //{
        //    FileStream picfs = new FileStream(@file1, FileMode.Open);
        //    FileStream fs = new FileStream(@file2, FileMode.OpenOrCreate);
        //    byte[] bytes = new byte[picfs.Length];
        //    picfs.Read(bytes, 0, (int)picfs.Length);
        //    picfs.Close();
        //    int blockSize = 0;
        //    if (crypt.KeySize == 1024)
        //        blockSize = 16;
        //    else blockSize = 8;
        //    byte[] rawblock, encryblock;
        //    for (int i = 0; i < bytes.Length; i += blockSize)
        //    {
        //        if ((bytes.Length - i) > blockSize)
        //            rawblock = new byte[blockSize];
        //        else rawblock = new byte[bytes.Length - i];
        //        Buffer.BlockCopy(bytes, i, rawblock, 0, rawblock.Length);
        //        encryblock = crypt.Encrypt(rawblock, false);
        //        fs.Write(encryblock, 0, encryblock.Length);
        //    }
        //    fs.Flush();
        //    fs.Close();
        //}
        //解密其它非文本文件，当然可以包括文本文件 
        //private void DecryptOther(string fileone, string filetwo)
        //{
        //    FileStream fs = new FileStream(@fileone, FileMode.Open);
        //    FileStream writopic = new FileStream(@filetwo, FileMode.Create);
        //    byte[] bytes = new byte[fs.Length];
        //    fs.Read(bytes, 0, (int)fs.Length);
        //    fs.Close();
        //    MemoryStream ms = new MemoryStream();
        //    int keySize = crypt.KeySize / 8;
        //    byte[] rawblock, decryptblock;
        //    for (int i = 0; i < bytes.Length; i += keySize)
        //    {
        //        if ((bytes.Length - i) > keySize)
        //        {
        //            rawblock = new byte[keySize];
        //        }
        //        else
        //        { rawblock = new byte[bytes.Length - i]; }

        //        Buffer.BlockCopy(bytes, i, rawblock, 0, rawblock.Length);
        //        decryptblock = crypt.Decrypt(rawblock, false);
        //        ms.Write(decryptblock, 0, decryptblock.Length);
        //    }
        //    ms.Position = 0;
        //    byte[] decode = new byte[ms.Length];
        //    ms.Read(decode, 0, (int)ms.Length);
        //    ms.Close();
        //    writopic.Write(decode, 0, decode.Length);
        //    writopic.Close();

        //}
        //创建一个函数，可以在线程中使用，经实验，效果不明显 
        //private void DecryptUsingThread()
        //{
        //    DecryptOther(textBox4.Text, textBox5.Text);
        //}

    }
}
